//  (C) Copyright visualfc 2008.
//  Use, modification and distribution are subject to the Boost Software License,
//  Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt).

//  vfc::type_id
//  generic typeid, not support rtti
//  version 0.2
//
//  simple:
//  vfc::type_id_t<int>().name()
//  vfc::type_id(100)().name()
//  vfc::type_id("ok")().name()
//
//  make vfc type_id :
//  VFC_MAKE_ID(std::string,0x2001)
//  VFC_MAKE_ID(std::vector<int>,0x2002)
//
//  struct a 
//	{
//		const int * test(int,int);
//	};
//  VFC_MAKE_ID(a,0x2003)
//  vfc::type_id(&a::test).name(); 

#ifndef _VFC_TYPE_ID_H_
#define _VFC_TYPE_ID_H_

#include <boost/type_traits/is_void.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_volatile.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_member_function_pointer.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/is_reference.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_class.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_volatile.hpp>
#include <boost/type_traits/remove_bounds.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/detail/is_function_ptr_tester.hpp>

namespace vfc
{

namespace detail
{
	//vfc::detail::is_function_ptr<T>::value

	template <class T>
		struct is_function_ptr_helper
	{
		static T& make_t();
		enum { value = sizeof(boost::type_traits::is_function_ptr_tester(is_function_ptr_helper<T>::make_t())) == sizeof(boost::type_traits::yes_type) };
	};
	template <>
		struct is_function_ptr_helper<void>
	{
		enum { value = 0};
	};
	
	template <int>
		struct is_function_ptr_select
	{
		template <class U>
			struct is_function_ptr_value
		{
			enum { value = 0};
		};
	};
	template<>
		struct is_function_ptr_select<0>
	{
		template <class U>
			struct is_function_ptr_value
		{
			enum { value = is_function_ptr_helper<U>::value };
		};
	};	
	
	template <class T>
		struct is_function_ptr
	{	
		enum { value = is_function_ptr_select<boost::is_reference<T>::value || boost::is_void<T>::value>::template is_function_ptr_value<T>::value };
	};
	
	template <>
		struct is_function_ptr<void>
	{
		enum { value = 0};
	};	
	
	//vfc::detail::type2type
	template <typename T>
		struct type2type
	{
		typedef T type;
	};
	template <int N>	
		struct int_size
	{
		enum { value = N};
		char dummy[N+1];
	};		
	template <>	
		struct int_size<0>
	{
		enum { value = 0};
		char dummy[1];
	};		

}; // namespace vfc::detail

}; //namespace vfc

namespace vfc
{

namespace detail
{

template <typename T >
struct type2id
{
	enum { value = 0 };
	enum { name_size = sizeof("{none}")-1 };
	static const char * name()
	{
		return "{none}";
	}
};


struct null_type {
	enum { modify = 0 };
	enum { array_size = 0 };
};

template <int N>
struct id2type
{
	typedef null_type type;
	enum { value = N };
	enum { name_size = sizeof("{none}")-1 };
	
	static const char * name()
	{
		return "{none}";
	}
};

template <int N>
struct id2size
{
	enum { size = 0 };
};
template<>
struct id2size<0>
{
	enum { size = 1 };
};

}; //namespace detail

}; // namespace vfc

namespace vfc
{

namespace detail
{

template <typename T>
struct is_null_type
{
	enum { value = 0};
};
template<>
struct is_null_type<null_type>
{
	enum { value = 1 };
};

//vfc::is_true<b>::then<T,U>::type;
template <bool b>
struct if_true
{
	template <typename T, typename U>
		struct then
	{
		typedef T type;
	};
	template <int N, int M>
	struct then_value
	{
		enum { value = N };
	};
};

template <>
struct if_true<false>
{
	template <typename T, typename U>
		struct then
	{
		typedef U type;
	};
	template <int N, int M>
	struct then_value
	{
		enum { value = M };
	};
};

template<int n_modify, int n_size, typename TInput, typename TOutput, typename TTail>
struct type_list
{
	enum { modify		= n_modify };
	enum { array_size	= n_size   };

	typedef TInput		itype;
	typedef TOutput		otype;
	typedef TTail		tail;
};

template <int N>
struct int2str_t
{
	enum { size = (N <= 9) ? 1 :
	(N <= 99 ? 2 :
	(N <= 999 ? 3 :
	(N <= 9999 ? 4 :
	(N <= 99999 ? 5 :
	(N <= 999999 ? 6 :
	(N <= 9999999 ? 7 : 
	(N <= 99999999 ? 8 : 
	(N <= 999999999 ? 9 : 
	10 ) ) )  ) ) ) ) ) };
	const char * operator()()
	{
		const int flag[] = {1,10,100,1000,10000,100000,100000,10000000,100000000,1000000000 };
		int i = 0;
		for (i = 0; i < size; i++)
		{
			buf[size-i-1] = N%(flag[i+1])/flag[i]+'0';
		}	
		buf[i] = '\0';
		return buf;
	}
	char buf[size+1];
};

template <int N>
struct int2array_t
{
	enum { size = (N <= 9) ? 1 :
	(N <= 99 ? 2 :
	(N <= 999 ? 3 :
	(N <= 9999 ? 4 :
	(N <= 99999 ? 5 :
	(N <= 999999 ? 6 :
	(N <= 9999999 ? 7 : 
	(N <= 99999999 ? 8 : 
	(N <= 999999999 ? 9 : 
	10 ) ) )  ) ) ) ) ) };
	const char * str()
	{
		const int flag[] = {1,10,100,1000,10000,100000,100000,10000000,100000000,1000000000 };
		int i = 0;
		buf[0] = '[';
		for (i = 0; i < size; i++)
		{
			buf[size-i] = N%(flag[i+1])/flag[i]+'0';
		}	
		buf[i+1] = ']';
		buf[i+2] = '\0';
		return buf;
	}
	char buf[size+1+2];
};

//const char flag[8][10] = {"","const","volitale","*","&","[]","",""};
template <int N>
struct int2flag_helper
{
	template <int array_size>
	struct flag
	{
		enum { name_size = 0 };
		const char * name()
		{
			return "";
		};
	};
};

#define MAKE_INT2FLAG(value,str)\
template <>\
struct int2flag_helper<value>\
{\
	template <int array_size>\
	struct flag\
	{\
	enum { name_size = sizeof(str)-1 };\
	const char * name()\
	{\
		return str;\
	}\
	};\
};
MAKE_INT2FLAG(1,"const");
MAKE_INT2FLAG(2,"volitale");
MAKE_INT2FLAG(3,"*");
MAKE_INT2FLAG(4,"&");
//MAKE_INT2FLAG(5,"[]");
MAKE_INT2FLAG(6,"");

template <>
struct int2flag_helper<5>
{
	template <int array_size>
	struct flag
	{
		int2array_t<array_size>	i2a;
		enum { name_size = int2array_t<array_size>::size+2 };
		const char * name()
		{
			return i2a.str();
		}
	};
};

template <int modify, int array_size>
struct int2flag : public int2flag_helper<modify>::template flag<array_size>
{
	enum { name_size = int2flag_helper<modify>::template flag<array_size>::name_size };
};

//for vc60 bug:	strcpy_t<T>(char *, const char *) function error
template <int len>
struct strcpy_t
{
	inline void operator()(char * dest, const char * source)
	{
		for (int i = 0; i < len; i++)
		{
			dest[i] = source[i];
		}
		dest[len] = '\0';
	}
};

template <typename TList>
struct type_list_helper
{
	typedef typename TList::tail  tail;
	typedef typename TList::itype type;
	typedef typename TList::otype otype;

	enum { length = 1 + type_list_helper<tail>::length };
	enum { name_size = 1 + int2flag<TList::modify,TList::array_size>::name_size + type_list_helper<typename TList::tail>::name_size};
	typedef typename if_true<length == 0>::template then<typename TList::otype, typename type_list_helper<typename TList::tail>::native_type>::type native_type;

	static inline int get_len()
	{
		return (length == 0 ? (int)id2type<TList::modify>::name_size : 
				(int)int2flag<TList::modify, TList::array_size>::name_size+1)
				+ type_list_helper<tail>::get_len();
	}

	static inline int get_modify_len()
	{
		return (length == 0 ? 0 : 
				(int)int2flag<TList::modify, TList::array_size>::name_size)
					+ (length != 0 && length != 1 ? 1 : 0 )
				+ type_list_helper<tail>::get_modify_len();
	}

	static inline void get_modify_name(char * str)
	{
		type_list_helper<tail>::get_modify_name(str);

		int size = type_list_helper<tail>::get_modify_len();

		if (length != 0)
		{
			if (length != 1)
				str[size++] = 0x20;
			strcpy_t<int2flag<TList::modify, TList::array_size>::name_size>()(&str[size],int2flag<TList::modify, TList::array_size>().name());
		}
	}

	static inline void get_name(char * str)
	{
		type_list_helper<tail>::get_name(str);

		int size = type_list_helper<tail>::get_len();

		if (length == 0)
		{
			strcpy_t<id2type<TList::modify>::name_size>()(&str[size], id2type<TList::modify>::name());
		}
		else
		{
			str[size++] = 0x20;
			strcpy_t<int2flag<TList::modify, TList::array_size>::name_size>()(&str[size],int2flag<TList::modify, TList::array_size>().name());
		}
	}

	template <int N>
	struct at_back
	{
		typedef typename if_true<N == 0>::template then<TList,typename type_list_helper<typename TList::tail>::template at_back<N-1>::list>::type list;
	};
	template <int N>
	struct at
	{
		typedef typename at_back<length-N>::list list;
	};
	template <int N>
	struct index
	{
		typedef typename at_back<length-N>::list type;
	};
};

template<>
struct type_list_helper<null_type>
{
	typedef null_type  tail;
	typedef null_type  type;
	typedef null_type  otype;

	enum { name_size = 0 };
	enum { length = -1 };

	typedef null_type native_type;

	template <int N>
	struct at
	{
		typedef null_type list;
	};
	template <int N>
	struct at_back
	{
		typedef null_type list;
	};
	template <int N>
	struct index
	{
		typedef null_type type;
	};
	static inline int get_modify_len()
	{
		return 0;
	}
	static inline int get_len()
	{
		return 0;
	}	
	static void get_modify_name(char * str)
	{
		str[0] = '\0';
	}
	static void get_name(char * str)
	{
		str[0] = '\0';
	}
};

template <typename T>
struct select_type_value
{
	enum { is_pointer   = boost::is_pointer<T>::value };
	enum { is_reference = boost::is_reference<T>::value };
	enum { is_array		= boost::is_array<T>::value };
	enum { is_const		= boost::is_const<T>::value };
	enum { is_volatile  = boost::is_volatile<T>::value };
	enum { is_function_ptr = detail::is_function_ptr<T>::value };

	enum { value = is_function_ptr ? 0 : 
		( is_array ? 5 :	
			(is_const ? 1 : 
				( is_volatile ? 2 : 
					( is_pointer ? 3 : 
						( is_reference ? 4 : 0
							))))) };
};

template <int N>
struct type_base_t_helper
{
};

template <>
struct type_base_t_helper<0>
{
	template <typename T>
		struct type_base_t_select
	{
		typedef T type;
		enum { value =  0};
		typedef type_list<type2id<T>::value,0,type,type,null_type>	list;
	};
};

template<>
struct type_base_t_helper<1>
{
	template <typename T>
		struct type_base_t_select
	{	
		typedef typename boost::remove_const<T>::type U;	
		enum { value = select_type_value<U>::value };		
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::type type;
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::list tail;
		typedef type_list<1,0,T,U,tail> list;
	};
};

template<>
struct type_base_t_helper<2>
{
	template <typename T>
		struct type_base_t_select
	{		
		typedef typename boost::remove_volatile<T>::type U;		
		enum { value = select_type_value<U>::value };		
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::type type;
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::list tail;
		typedef type_list<2,0,T,U,tail> list;
	};
};

template<>
struct type_base_t_helper<3>
{
	template <typename T>
		struct type_base_t_select
	{
		typedef typename boost::remove_pointer<T>::type U;		
		enum { value = select_type_value<U>::value };		
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::type type;
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::list tail;
		typedef type_list<3,0,T,U,tail> list;
	};
};

template<>
struct type_base_t_helper<4>
{
	template <typename T>
		struct type_base_t_select
	{
		typedef typename boost::remove_reference<T>::type U;
		enum { value = select_type_value<U>::value };	
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::type type;
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::list tail;
		typedef type_list<4,0,T,U,tail> list;
	};
};

template<>
struct type_base_t_helper<5>
{
	template <typename T>
		struct type_base_t_select
	{
		typedef typename boost::remove_bounds<T>::type U;
		enum { value = select_type_value<U>::value };	
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::type type;
		typedef typename type_base_t_helper<value>::template type_base_t_select<U>::list tail;
		typedef type_list<5,sizeof(T)/ sizeof(U),T,U,tail> list;
	};
};


template <typename T>
struct select_function_value
{
	enum { is_function_ptr = detail::is_function_ptr<T>::value };
	enum { is_member_function_pointer = boost::is_member_function_pointer<T>::value };
	enum { is_null_type = is_null_type<T>::value };

	enum { value = is_null_type ? 0 :
				(is_function_ptr ? 1 : 
					( is_member_function_pointer ? 2 :	0 ) )};
};

template <typename T>
struct type_base_t
{
	typedef T		type;
	typedef typename detail::type_base_t_helper<detail::select_type_value<T>::value>::template type_base_t_select<T>::type native_type;
	typedef typename detail::type_base_t_helper<detail::select_type_value<T>::value>::template type_base_t_select<T>::list list;

	enum { native = type2id<native_type>::value };
	enum { length = type_list_helper<list>::length };

	enum { is_function_ptr = boost::is_function<native_type>::value };
	enum { is_class = boost::is_class<native_type>::value };
	enum { is_nonedef = native == 0 };


	inline static const char * native_name()
	{
		return type2id<native_type>::name();
	}

	inline static const char * name()
	{
		return type_list_helper<list>::name();
	}

	inline static const char * modify_name()
	{
		return type_list_helper<list>::modify_name();
	}
};	// class type_base_t

template <typename T, int N>
struct type_list_index
{
	typedef typename type_base_t<T>::list _list;
	typedef typename type_list_helper<_list>::template index<N>::type list;
	
	enum { length =  type_list_helper<_list>::length };
	enum { modify = list::modify };
	enum { array_size = list::array_size };
};

template <int n_arity, 
		  typename R, 
		  typename T1 = type_list_index<null_type,0>,
		  typename T2 = type_list_index<null_type,0>,
		  typename T3 = type_list_index<null_type,0>,
		  typename T4 = type_list_index<null_type,0>,
		  typename T5 = type_list_index<null_type,0>,
		  typename T6 = type_list_index<null_type,0>,
		  typename T7 = type_list_index<null_type,0>,
		  typename T8 = type_list_index<null_type,0>,
		  typename T9 = type_list_index<null_type,0>
		  >
struct function_state_helper
{
	detail::int_size<n_arity>			arity;

	detail::int_size<R::length>			result_length;
	detail::int_size<R::modify>			result;
	detail::int_size<R::array_size>		result_size;

	detail::int_size<T1::length>		arg1_length;
	detail::int_size<T1::modify>		arg1_value;
	detail::int_size<T1::array_size>	arg1_size;

	detail::int_size<T2::length>		arg2_length;
	detail::int_size<T2::modify>		arg2_value;
	detail::int_size<T2::array_size>	arg2_size;

	detail::int_size<T3::length>		arg3_length;
	detail::int_size<T3::modify>		arg3_value;
	detail::int_size<T3::array_size>	arg3_size;

	detail::int_size<T4::length>		arg4_length;
	detail::int_size<T4::modify>		arg4_value;
	detail::int_size<T4::array_size>	arg4_size;
	
	detail::int_size<T5::length>		arg5_length;
	detail::int_size<T5::modify>		arg5_value;
	detail::int_size<T5::array_size>	arg5_size;
	
	detail::int_size<T6::length>		arg6_length;
	detail::int_size<T6::modify>		arg6_value;
	detail::int_size<T6::array_size>	arg6_size;
	
	detail::int_size<T7::length>		arg7_length;
	detail::int_size<T7::modify>		arg7_value;
	detail::int_size<T7::array_size>	arg7_size;
	
	detail::int_size<T8::length>		arg8_length;
	detail::int_size<T8::modify>		arg8_value;
	detail::int_size<T8::array_size>	arg8_size;
	
	detail::int_size<T9::length>		arg9_length;
	detail::int_size<T9::modify>		arg9_value;
	detail::int_size<T9::array_size>	arg9_size;

};


template <int N>
struct type_list_function_helper
{
	template <typename T>
	struct function_type
	{
		static T & make();
		
		template <typename R>
			static function_state_helper<0,	
										type_list_index<R,N> 
										>
										test( R (*) (void));
			
		template <typename R, typename T1>
			static function_state_helper<1,	
										type_list_index<R,N> ,
										type_list_index<T1,N> 
										>
										test( R (*) (T1));

		template <typename R, typename T1, typename T2>
			static function_state_helper<2,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> 
										>
										test( R (*) (T1,T2));

		template <typename R, typename T1, typename T2, typename T3>
			static function_state_helper<3,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N>
										>
										test( R (*) (T1,T2,T3));
		
		template <typename R, typename T1, typename T2, typename T3, typename T4>
			static function_state_helper<4,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> 
										>
										test( R (*) (T1,T2,T3,T4));

		template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5>
			static function_state_helper<5,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N>
										>
										test( R (*) (T1,T2,T3,T4,T5));

		template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
			static function_state_helper<6,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N>
										>
										test( R (*) (T1,T2,T3,T4,T5,T6));

		template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
			static function_state_helper<7,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N>
										>
										test( R (*) (T1,T2,T3,T4,T5,T6,T7));

		template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
			static function_state_helper<8,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N>
										>
										test( R (*) (T1,T2,T3,T4,T5,T6,T7,T8));

		template <typename R, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
			static function_state_helper<9,
										type_list_index<R,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N> ,
										type_list_index<T9,N>
										>
										test( R (*) (T1,T2,T3,T4,T5,T6,T7,T8,T9));

		enum { arity		= sizeof(test(make()).arity) -1			};

		enum { result_length= sizeof(test(make()).result_length)-1	};
		enum { result		= sizeof(test(make()).result)-1			};
		enum { result_size	= sizeof(test(make()).result_size)-1	};

		enum { arg1_length  = sizeof(test(make()).arg1_length)-1	};
		enum { arg1_value	= sizeof(test(make()).arg1_value)-1			};
		enum { arg1_size	= sizeof(test(make()).arg1_size)-1		};

		enum { arg2_length  = sizeof(test(make()).arg2_length)-1	};
		enum { arg2_value	= sizeof(test(make()).arg2_value)-1			};
		enum { arg2_size	= sizeof(test(make()).arg2_size)-1		};

		enum { arg3_length  = sizeof(test(make()).arg3_length)-1	};
		enum { arg3_value	= sizeof(test(make()).arg3_value)-1			};
		enum { arg3_size	= sizeof(test(make()).arg3_size)-1		};

		enum { arg4_length  = sizeof(test(make()).arg4_length)-1	};
		enum { arg4_value	= sizeof(test(make()).arg4_value)-1			};
		enum { arg4_size	= sizeof(test(make()).arg4_size)-1		};

		enum { arg5_length  = sizeof(test(make()).arg5_length)-1	};
		enum { arg5_value	= sizeof(test(make()).arg5_value)-1			};
		enum { arg5_size	= sizeof(test(make()).arg5_size)-1		};

		enum { arg6_length  = sizeof(test(make()).arg6_length)-1	};
		enum { arg6_value	= sizeof(test(make()).arg6_value)-1			};
		enum { arg6_size	= sizeof(test(make()).arg6_size)-1		};

		enum { arg7_length  = sizeof(test(make()).arg7_length)-1	};
		enum { arg7_value	= sizeof(test(make()).arg7_value)-1			};
		enum { arg7_size	= sizeof(test(make()).arg7_size)-1		};
		
		enum { arg8_length  = sizeof(test(make()).arg8_length)-1	};
		enum { arg8_value	= sizeof(test(make()).arg8_value)-1			};
		enum { arg8_size	= sizeof(test(make()).arg8_size)-1		};
		
		enum { arg9_length  = sizeof(test(make()).arg9_length)-1	};
		enum { arg9_value	= sizeof(test(make()).arg9_value)-1			};
		enum { arg9_size	= sizeof(test(make()).arg9_size)-1		};
		
		typedef type_list<result,result_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::result_list>::type> result_list;

		typedef type_list<arg1_value,arg1_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg1_list>::type> arg1_list;

		typedef type_list<arg2_value,arg2_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg2_list>::type> arg2_list;

		typedef type_list<arg3_value,arg3_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg3_list>::type> arg3_list;

		typedef type_list<arg4_value,arg4_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg4_list>::type> arg4_list;
		
		typedef type_list<arg5_value,arg5_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg5_list>::type> arg5_list;
		
		typedef type_list<arg6_value,arg6_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg6_list>::type> arg6_list;
		
		typedef type_list<arg7_value,arg7_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg7_list>::type> arg7_list;
		
		typedef type_list<arg8_value,arg8_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg8_list>::type> arg8_list;
		
		typedef type_list<arg9_value,arg9_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_function_helper<N-1>::template function_type<T>::arg9_list>::type> arg9_list;
	};
};

template<>
struct type_list_function_helper<-1>
{	
	template <typename T>
	struct function_type
	{
		typedef null_type result_list;
		typedef null_type arg1_list;
		typedef null_type arg2_list;
		typedef null_type arg3_list;
		typedef null_type arg4_list;
		typedef null_type arg5_list;
		typedef null_type arg6_list;
		typedef null_type arg7_list;
		typedef null_type arg8_list;
		typedef null_type arg9_list;
	};
};
template <typename T, typename U>
struct type_id_list_t
{
	typedef T type;
	typedef U tail;
};

template <int N>
struct type_list_function_index
{
	template <typename TList, int arity>
	struct type_helper
	{
		typedef typename TList::type type;
		typedef typename TList::tail tail;

		inline static int get_len()
		{
			return ( (N == arity-1) ? 
				(type_list_helper<type>::get_modify_len() + 5) : 
				 type_list_helper<type>::get_len() ) +
					 (N == arity ? 1 : 0 ) +
					 (N != arity && N != arity-1 && N != 0 ? 1 : 0) +
				type_list_function_index<N-1>::template type_helper<tail,arity>::get_len() ;
		}
		inline static void get_name(char * str)
		{
			int size = type_list_helper<type>::get_len();
			if (N == arity-1)
			{
				size = type_list_helper<type>::get_modify_len();
				strcpy_t<2>()(str,"(*");
				type_list_helper<type>::get_modify_name(str+2);
				size += 2;
				strcpy_t<2>()(str+size,")(");
				size += 2;
			}
			else
			{
				type_list_helper<type>::get_name(str);
			}
			
			if (N == arity)
			{
				str[size++] = 0x20;
			}
			else if (N != arity-1 && N != 0)
			{
				str[size++] = ',';
			}
			
			type_list_function_index<N-1>::template type_helper<tail,arity>::get_name(str+size);
		}
	};
};
template<>
struct type_list_function_index<-1>
{
	template <typename TList, int arity>
	struct type_helper
	{
		inline static int get_len()
		{
			return 0;
		}
		inline static void get_name(char * str)
		{
			strcpy_t<1>()(str,")");
		}
	};
};

//const char flag[][20] = {"","const","volatile","const volatile"};
template <int N>
struct member_function_int2flag
{
	enum { name_size = 0 };
	const char * name()
	{
		return "";
	};
};
#define MAKE_MEMBER_FUNCTION_INT2FLAG(id,flag)\
template <>\
struct member_function_int2flag<id>\
{\
	enum { name_size = sizeof(flag)-1 };\
	const char * name()\
	{\
		return flag;\
	};\
};
MAKE_MEMBER_FUNCTION_INT2FLAG(1,"const");
MAKE_MEMBER_FUNCTION_INT2FLAG(2,"volatile");
MAKE_MEMBER_FUNCTION_INT2FLAG(3,"const volatile");

template <int N>
struct type_list_member_function_index
{
	template <typename TList, int arity, int cv_type>
	struct type_helper
	{
		typedef typename TList::type type;
		typedef typename TList::tail tail;

		inline static int get_len()
		{
			return ( (N == arity-2) ? 
				(type_list_helper<type>::get_modify_len()+3) : 
				 type_list_helper<type>::get_len() ) +
					 (N == arity -1 ? 4 : 0) +
					 (N == arity ? 1 : 0) +
					 (N != arity && N != arity-1 && N != arity-2 && N != 0 ? 1 : 0) +
					 (N == 0 && cv_type != 0 ? member_function_int2flag<cv_type>::name_size : 0 ) +
				type_list_member_function_index<N-1>::template type_helper<tail,arity,cv_type>::get_len() ;
		}
		inline static void get_name(char * str)
		{
			int size = type_list_helper<type>::get_len();
			if (N == arity-1)
			{
				str[0] = '(';
				type_list_helper<type>::get_name(str+1);
				size++;
				strcpy_t<3>()(str+size,"::*");
				size += 3;
			}
			else if (N == arity-2)
			{
				size = type_list_helper<type>::get_modify_len();
				type_list_helper<type>::get_modify_name(str);
				strcpy_t<2>()(str+size,")(");
				size += 2;
			}
			else
			{
				type_list_helper<type>::get_name(str);
			}
			if (N == arity)
			{
				str[size++] += 0x20;
			}
			else if (N != arity-1 && N != arity-2 && N != 0)
			{
				str[size++] += ',';
			}

			type_list_member_function_index<N-1>::template type_helper<tail,arity,cv_type>::get_name(str+size);

			if (N == 0 && cv_type != 0)
			{
				size++;
				strcpy_t<member_function_int2flag<cv_type>::name_size>()(str+size,member_function_int2flag<cv_type>().name());
			}
		}
	};
};
template<>
struct type_list_member_function_index<-1>
{
	template <typename TList, int arity, int cv_type>
	struct type_helper
	{
		inline static int get_len()
		{
			return 0;
		}
		inline static void get_name(char * str)
		{
			strcpy_t<1>()(str,")");
		}
	};
};


template <typename T, typename TList>
struct type_list_function
{
	enum { arity = type_list_function_helper<0>::template function_type<T>::arity }; 

	enum { result_length = type_list_function_helper<0>::template function_type<T>::result_length }; 
	enum { arg1_length = type_list_function_helper<0>::template function_type<T>::arg1_length }; 
	enum { arg2_length = type_list_function_helper<0>::template function_type<T>::arg2_length }; 
	enum { arg3_length = type_list_function_helper<0>::template function_type<T>::arg3_length }; 
	enum { arg4_length = type_list_function_helper<0>::template function_type<T>::arg4_length }; 
	enum { arg5_length = type_list_function_helper<0>::template function_type<T>::arg5_length }; 
	enum { arg6_length = type_list_function_helper<0>::template function_type<T>::arg6_length }; 
	enum { arg7_length = type_list_function_helper<0>::template function_type<T>::arg7_length }; 
	enum { arg8_length = type_list_function_helper<0>::template function_type<T>::arg8_length }; 
	enum { arg9_length = type_list_function_helper<0>::template function_type<T>::arg9_length }; 

	typedef typename type_list_function_helper<result_length>::template function_type<T>::result_list result_list;
	typedef typename type_list_function_helper<arg1_length>::template function_type<T>::arg1_list	 arg1_list;
	typedef typename type_list_function_helper<arg2_length>::template function_type<T>::arg2_list	 arg2_list;
	typedef typename type_list_function_helper<arg3_length>::template function_type<T>::arg3_list	 arg3_list;
	typedef typename type_list_function_helper<arg4_length>::template function_type<T>::arg4_list	 arg4_list;
	typedef typename type_list_function_helper<arg5_length>::template function_type<T>::arg5_list	 arg5_list;
	typedef typename type_list_function_helper<arg6_length>::template function_type<T>::arg6_list	 arg6_list;
	typedef typename type_list_function_helper<arg7_length>::template function_type<T>::arg7_list	 arg7_list;
	typedef typename type_list_function_helper<arg8_length>::template function_type<T>::arg8_list	 arg8_list;
	typedef typename type_list_function_helper<arg9_length>::template function_type<T>::arg9_list	 arg9_list;

	typedef type_id_list_t<result_list,
			type_id_list_t<TList,
			type_id_list_t<arg1_list,
			type_id_list_t<arg2_list,
			type_id_list_t<arg3_list,
			type_id_list_t<arg4_list,
			type_id_list_t<arg5_list,
			type_id_list_t<arg6_list,
			type_id_list_t<arg7_list,
			type_id_list_t<arg8_list,
			type_id_list_t<arg9_list,null_type> > > > > > > > > > > type_list;
};

template <int n_arity,
		  typename R, 
		  typename CLS,
		  typename T1 = type_list_index<null_type,0>,
		  typename T2 = type_list_index<null_type,0>,
		  typename T3 = type_list_index<null_type,0>,
		  typename T4 = type_list_index<null_type,0>,
		  typename T5 = type_list_index<null_type,0>,
		  typename T6 = type_list_index<null_type,0>,
		  typename T7 = type_list_index<null_type,0>,
		  typename T8 = type_list_index<null_type,0>,
		  typename T9 = type_list_index<null_type,0>
		  >
struct member_function_state_helper : 
		public function_state_helper<n_arity/10,R,T1,T2,T3,T4,T5,T6,T7,T8,T9>
{
	detail::int_size<CLS::length>		cls_length;
	detail::int_size<CLS::modify>		cls;
	detail::int_size<CLS::array_size>	cls_size;
	detail::int_size<n_arity%10>		cv_type;
};

template <int N>
struct type_list_member_function_helper
{
	template <typename T>
	struct function_type
	{
		static T & make();
		
		template <typename R, typename CLS>
			static member_function_state_helper<0,	
										type_list_index<R,N> ,
										type_list_index<CLS,N> 
										>
										test( R (CLS::*) (void));
			
		template <typename R, typename CLS>
			static member_function_state_helper<01,	
										type_list_index<R,N> ,
										type_list_index<CLS,N> 
										>
										test( R (CLS::*) (void) const);

		template <typename R, typename CLS>
			static member_function_state_helper<02,	
										type_list_index<R,N> ,
										type_list_index<CLS,N> 
										>
										test( R (CLS::*) (void) volatile);

		template <typename R, typename CLS>
			static member_function_state_helper<03,	
										type_list_index<R,N> ,
										type_list_index<CLS,N> 
										>
										test( R (CLS::*) (void) const volatile);

		template <typename R, typename CLS, typename T1>
			static member_function_state_helper<10,	
										type_list_index<R,N> ,
										type_list_index<CLS,N>, 
										type_list_index<T1,N> 
										>
										test( R (CLS::*) (T1));

		template <typename R, typename CLS, typename T1>
			static member_function_state_helper<11,	
										type_list_index<R,N> ,
										type_list_index<CLS,N>, 
										type_list_index<T1,N> 
										>
										test( R (CLS::*) (T1) const);

		template <typename R, typename CLS, typename T1>
			static member_function_state_helper<12,	
										type_list_index<R,N> ,
										type_list_index<CLS,N>, 
										type_list_index<T1,N> 
										>
										test( R (CLS::*) (T1) volatile);

		template <typename R, typename CLS, typename T1>
			static member_function_state_helper<13,	
										type_list_index<R,N> ,
										type_list_index<CLS,N>, 
										type_list_index<T1,N> 
										>
										test( R (CLS::*) (T1) const volatile);

		template <typename R, typename CLS, typename T1, typename T2>
			static member_function_state_helper<20,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> 
										>
										test( R (CLS::*) (T1,T2));

		template <typename R, typename CLS, typename T1, typename T2>
			static member_function_state_helper<21,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> 
										>
										test( R (CLS::*) (T1,T2) const);

		template <typename R, typename CLS, typename T1, typename T2>
			static member_function_state_helper<22,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> 
										>
										test( R (CLS::*) (T1,T2) volatile);

		template <typename R, typename CLS, typename T1, typename T2>
			static member_function_state_helper<23,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> 
										>
										test( R (CLS::*) (T1,T2) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3>
			static member_function_state_helper<30,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> 
										>
										test( R (CLS::*) (T1,T2,T3));

		template <typename R, typename CLS, typename T1, typename T2, typename T3>
			static member_function_state_helper<31,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> 
										>
										test( R (CLS::*) (T1,T2,T3) const);
		
		template <typename R, typename CLS, typename T1, typename T2, typename T3>
			static member_function_state_helper<32,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> 
										>
										test( R (CLS::*) (T1,T2,T3) volatile);
		
		template <typename R, typename CLS, typename T1, typename T2, typename T3>
			static member_function_state_helper<33,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> 
										>
										test( R (CLS::*) (T1,T2,T3) const volatile);
		
		
		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4>
			static member_function_state_helper<40,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> 
										>
										test( R (CLS::*) (T1,T2,T3,T4));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4>
			static member_function_state_helper<41,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> 
										>
										test( R (CLS::*) (T1,T2,T3,T4) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4>
			static member_function_state_helper<42,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> 
										>
										test( R (CLS::*) (T1,T2,T3,T4) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4>
			static member_function_state_helper<43,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> 
										>
										test( R (CLS::*) (T1,T2,T3,T4) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5>
			static member_function_state_helper<50,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5>
			static member_function_state_helper<51,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5>
			static member_function_state_helper<52,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5>
			static member_function_state_helper<53,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
			static member_function_state_helper<60,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
			static member_function_state_helper<61,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
			static member_function_state_helper<62,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
			static member_function_state_helper<63,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
			static member_function_state_helper<70,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
			static member_function_state_helper<71,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
			static member_function_state_helper<72,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
			static member_function_state_helper<73,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
			static member_function_state_helper<80,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
			static member_function_state_helper<81,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
			static member_function_state_helper<82,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
			static member_function_state_helper<83,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8) const volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
			static member_function_state_helper<90,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N> ,
										type_list_index<T9,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8,T9));

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
			static member_function_state_helper<91,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N> ,
										type_list_index<T9,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8,T9) const);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
			static member_function_state_helper<92,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N> ,
										type_list_index<T9,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8,T9) volatile);

		template <typename R, typename CLS, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
			static member_function_state_helper<93,
										type_list_index<R,N> ,
										type_list_index<CLS,N> ,
										type_list_index<T1,N> ,
										type_list_index<T2,N> ,
										type_list_index<T3,N> ,
										type_list_index<T4,N> ,
										type_list_index<T5,N> ,
										type_list_index<T6,N> ,
										type_list_index<T7,N> ,
										type_list_index<T8,N> ,
										type_list_index<T9,N>
										>
										test( R (CLS::*) (T1,T2,T3,T4,T5,T6,T7,T8,T9) const volatile);

		enum { arity		= sizeof(test(make()).arity) -1			};
		enum { cv_type		= sizeof(test(make()).cv_type) -1		};

		enum { result_length= sizeof(test(make()).result_length)-1	};
		enum { result		= sizeof(test(make()).result)-1			};
		enum { result_size	= sizeof(test(make()).result_size)-1	};

		enum { arg1_length  = sizeof(test(make()).arg1_length)-1	};
		enum { arg1_value	= sizeof(test(make()).arg1_value)-1			};
		enum { arg1_size	= sizeof(test(make()).arg1_size)-1		};

		enum { arg2_length  = sizeof(test(make()).arg2_length)-1	};
		enum { arg2_value	= sizeof(test(make()).arg2_value)-1			};
		enum { arg2_size	= sizeof(test(make()).arg2_size)-1		};

		enum { arg3_length  = sizeof(test(make()).arg3_length)-1	};
		enum { arg3_value	= sizeof(test(make()).arg3_value)-1			};
		enum { arg3_size	= sizeof(test(make()).arg3_size)-1		};

		enum { arg4_length  = sizeof(test(make()).arg4_length)-1	};
		enum { arg4_value	= sizeof(test(make()).arg4_value)-1			};
		enum { arg4_size	= sizeof(test(make()).arg4_size)-1		};

		enum { arg5_length  = sizeof(test(make()).arg5_length)-1	};
		enum { arg5_value	= sizeof(test(make()).arg5_value)-1			};
		enum { arg5_size	= sizeof(test(make()).arg5_size)-1		};

		enum { arg6_length  = sizeof(test(make()).arg6_length)-1	};
		enum { arg6_value	= sizeof(test(make()).arg6_value)-1			};
		enum { arg6_size	= sizeof(test(make()).arg6_size)-1		};

		enum { arg7_length  = sizeof(test(make()).arg7_length)-1	};
		enum { arg7_value	= sizeof(test(make()).arg7_value)-1			};
		enum { arg7_size	= sizeof(test(make()).arg7_size)-1		};
		
		enum { arg8_length  = sizeof(test(make()).arg8_length)-1	};
		enum { arg8_value	= sizeof(test(make()).arg8_value)-1			};
		enum { arg8_size	= sizeof(test(make()).arg8_size)-1		};
		
		enum { arg9_length  = sizeof(test(make()).arg9_length)-1	};
		enum { arg9_value	= sizeof(test(make()).arg9_value)-1			};
		enum { arg9_size	= sizeof(test(make()).arg9_size)-1		};

		enum { cls_length	= sizeof(test(make()).cls_length)-1		};
		enum { cls			= sizeof(test(make()).cls)-1			};
		enum { cls_size		= sizeof(test(make()).cls_size)-1		};

		typedef type_list<result,result_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::result_list>::type> result_list;

		typedef type_list<arg1_value,arg1_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg1_list>::type> arg1_list;

		typedef type_list<arg2_value,arg2_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg2_list>::type> arg2_list;

		typedef type_list<arg3_value,arg3_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg3_list>::type> arg3_list;

		typedef type_list<arg4_value,arg4_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg4_list>::type> arg4_list;
		
		typedef type_list<arg5_value,arg5_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg5_list>::type> arg5_list;
		
		typedef type_list<arg6_value,arg6_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg6_list>::type> arg6_list;
		
		typedef type_list<arg7_value,arg7_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg7_list>::type> arg7_list;
		
		typedef type_list<arg8_value,arg8_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg8_list>::type> arg8_list;
		
		typedef type_list<arg9_value,arg9_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::arg9_list>::type> arg9_list;

		typedef type_list<cls,cls_size,T,T, typename
			if_true<N == 0>::template then<null_type,
			typename type_list_member_function_helper<N-1>::template function_type<T>::cls_list>::type> cls_list;

	};
};

template<>
struct type_list_member_function_helper<-1>
{	
	template <typename T>
	struct function_type
	{
		typedef null_type result_list;
		typedef null_type arg1_list;
		typedef null_type arg2_list;
		typedef null_type arg3_list;
		typedef null_type arg4_list;
		typedef null_type arg5_list;
		typedef null_type arg6_list;
		typedef null_type arg7_list;
		typedef null_type arg8_list;
		typedef null_type arg9_list;
		typedef null_type cls_list;
	};
};

template <typename T, typename TList>
struct type_list_member_function
{
	enum { arity = type_list_member_function_helper<0>::template function_type<T>::arity }; 
	enum { cv_type = type_list_member_function_helper<0>::template function_type<T>::cv_type }; 

	enum { result_length = type_list_member_function_helper<0>::template function_type<T>::result_length }; 
	enum { arg1_length = type_list_member_function_helper<0>::template function_type<T>::arg1_length }; 
	enum { arg2_length = type_list_member_function_helper<0>::template function_type<T>::arg2_length }; 
	enum { arg3_length = type_list_member_function_helper<0>::template function_type<T>::arg3_length }; 
	enum { arg4_length = type_list_member_function_helper<0>::template function_type<T>::arg4_length }; 
	enum { arg5_length = type_list_member_function_helper<0>::template function_type<T>::arg5_length }; 
	enum { arg6_length = type_list_member_function_helper<0>::template function_type<T>::arg6_length }; 
	enum { arg7_length = type_list_member_function_helper<0>::template function_type<T>::arg7_length }; 
	enum { arg8_length = type_list_member_function_helper<0>::template function_type<T>::arg8_length }; 
	enum { arg9_length = type_list_member_function_helper<0>::template function_type<T>::arg9_length }; 
	enum { cls_length = type_list_member_function_helper<0>::template function_type<T>::cls_length }; 

	typedef typename type_list_member_function_helper<result_length>::template function_type<T>::result_list result_list;
	typedef typename type_list_member_function_helper<arg1_length>::template function_type<T>::arg1_list	 arg1_list;
	typedef typename type_list_member_function_helper<arg2_length>::template function_type<T>::arg2_list	 arg2_list;
	typedef typename type_list_member_function_helper<arg3_length>::template function_type<T>::arg3_list	 arg3_list;
	typedef typename type_list_member_function_helper<arg4_length>::template function_type<T>::arg4_list	 arg4_list;
	typedef typename type_list_member_function_helper<arg5_length>::template function_type<T>::arg5_list	 arg5_list;
	typedef typename type_list_member_function_helper<arg6_length>::template function_type<T>::arg6_list	 arg6_list;
	typedef typename type_list_member_function_helper<arg7_length>::template function_type<T>::arg7_list	 arg7_list;
	typedef typename type_list_member_function_helper<arg8_length>::template function_type<T>::arg8_list	 arg8_list;
	typedef typename type_list_member_function_helper<arg9_length>::template function_type<T>::arg9_list	 arg9_list;
	typedef typename type_list_member_function_helper<cls_length>::template function_type<T>::cls_list		 cls_list;

	typedef type_id_list_t<result_list,
			type_id_list_t<cls_list,
			type_id_list_t<TList,
			type_id_list_t<arg1_list,
			type_id_list_t<arg2_list,
			type_id_list_t<arg3_list,
			type_id_list_t<arg4_list,
			type_id_list_t<arg5_list,
			type_id_list_t<arg6_list,
			type_id_list_t<arg7_list,
			type_id_list_t<arg8_list,
			type_id_list_t<arg9_list,null_type> > > > > > > > > > > > type_list;
};

template <int N>
struct type_id_helper_t
{
	template <typename T, typename TList>
	struct function_select
	{
		typedef type_id_list_t<TList,null_type> type_list;
		static inline int get_len()
		{
			return type_list_helper<TList>::get_len();
		}
		static void get_name(char * str)
		{
			type_list_helper<TList>::get_name(str);
		}
	};
};
template <>
struct type_id_helper_t<1>
{
	template <typename T, typename TList>
		struct function_select : public type_list_function<T, TList>
	{
		static inline int get_len()
		{
			typedef typename type_list_function<T, TList>::type_list type_list;
			enum { arity = type_list_function<T, TList>::arity };
			return type_list_function_index<arity+1>::template type_helper<type_list,arity+1>::get_len();
		}

		static void get_name(char * str)
		{
			typedef typename type_list_function<T, TList>::type_list type_list;
			enum { arity = type_list_function<T, TList>::arity };
			type_list_function_index<arity+1>::template type_helper<type_list,arity+1>::get_name(str);
		}
	};
};
template <>
struct type_id_helper_t<2>
{
	template <typename T, typename TList>
		struct function_select : public type_list_member_function<T,TList>
	{
		static inline int get_len()
		{
			typedef typename type_list_member_function<T, TList>::type_list type_list;
			enum { arity = type_list_member_function<T, TList>::arity };
			enum { cv_type = type_list_member_function<T, TList>::cv_type };
			return type_list_member_function_index<arity+2>::template type_helper<type_list,arity+2, cv_type>::get_len();
		}
		static void get_name(char * str)
		{
			typedef typename type_list_member_function<T, TList>::type_list type_list;
			enum { arity = type_list_member_function<T, TList>::arity };
			enum { cv_type = type_list_member_function<T, TList>::cv_type };
			type_list_member_function_index<arity+2>::template type_helper<type_list,arity+2, cv_type>::get_name(str);
		}
	};
};

}; //namespace detail


template <typename T>
struct type_id_t
{
	typedef T		type;
	typedef typename detail::type_base_t_helper<detail::select_type_value<T>::value>::template type_base_t_select<T>::type native_type;
	typedef typename detail::type_base_t_helper<detail::select_type_value<T>::value>::template type_base_t_select<T>::list type_list;
	typedef typename detail::type_id_helper_t<detail::select_function_value<native_type>::value>::template function_select<native_type, type_list>::type_list  type_id_list;
	
	static inline int get_len()
	{
		return detail::type_id_helper_t<detail::select_function_value<native_type>::value>::template function_select<native_type, type_list>::get_len(); 
	}
	static inline void get_name(char * str)
	{
		detail::type_id_helper_t<detail::select_function_value<native_type>::value>::template function_select<native_type, type_list>::get_name(str); 
	}

	inline const char * name()
	{
		if (_name == 0)
		{
			_name = new char[get_len()+1];
			get_name(_name);
		}
		return (const char*)_name;
	}

	static inline const int local_id()
	{
		return (int)&local_id;
	}

	type_id_t() : _name(0)
	{
	}
	~type_id_t()
	{
		if (_name)
			delete[] _name;
	}
	type_id_t(const type_id_t & other) : _name(0)
	{
	}
protected:
	type_id_t<T> & operator = (const type_id_t & other); 
	char * _name;
};

template <typename T>
inline type_id_t<T> type_id(const T & t)
{
	return type_id_t<T>();
}

}; //namespace vfc


//define VFC_TYPE_ID
//for vc60 bug:	typedef type_base_t<_type>::type native_type
#define VFC_TYPE_ID(_type, id)	\
namespace vfc \
{\
namespace detail \
{\
template<>	\
struct type2id< _type >\
{\
	enum { value = id };\
	enum { name_size = sizeof(#_type)-1 };\
	static const char * name()\
	{\
		return #_type;\
	}\
};\
template<>\
struct id2type<id>	\
{	\
	typedef detail::type2type<_type>::type type;	\
	typedef detail::type_base_t<_type>::native_type native_type;	\
	enum { name_size = sizeof(#_type)-1 };\
	static const char * name()\
	{\
		return #_type;\
	}\
};\
};\
}; //namespace vfc


VFC_TYPE_ID(char,0x1000);
VFC_TYPE_ID(unsigned char,0x1001);
VFC_TYPE_ID(short,0x1002);
VFC_TYPE_ID(unsigned short,0x1003);
VFC_TYPE_ID(int,0x1004);
VFC_TYPE_ID(unsigned int,0x1005);
VFC_TYPE_ID(long,0x1006);
VFC_TYPE_ID(unsigned long,0x1007);
VFC_TYPE_ID(float,0x1008);
VFC_TYPE_ID(double,0x1009);
VFC_TYPE_ID(void,0x1010);


#endif // _VFC_TYPE_ID_H_

